package org.budo.dubbo.protocol.async.repository;

import java.io.Serializable;

import com.alibaba.dubbo.rpc.Invocation;
import com.alibaba.dubbo.rpc.RpcInvocation;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import lombok.experimental.Accessors;

/**
 * 重新做了一个Invocation，用于序列化
 * 
 * @author limingwei
 */
@Getter
@Setter
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class BudoAsyncInvocation implements Serializable {
    private static final long serialVersionUID = 7636819924353706115L;

    /**
     * 以 dubbo.Invocation 的 hashCode 为 id
     */
    private Integer id;

    /**
     * 消息创建时间，发消息前写入
     */
    private Long createdAt;

    private String methodName;

    private Class<?>[] parameterTypes;

    private Object[] arguments;

    public static BudoAsyncInvocation fromDubboInvocation(Invocation invocation) {
        BudoAsyncInvocation budoAsyncInvocation = new BudoAsyncInvocation();
        budoAsyncInvocation.setMethodName(invocation.getMethodName());
        budoAsyncInvocation.setParameterTypes(invocation.getParameterTypes());
        budoAsyncInvocation.setArguments(invocation.getArguments());

        budoAsyncInvocation.setCreatedAt(System.currentTimeMillis()); // 消息创建时间
        budoAsyncInvocation.setId(invocation.hashCode());
        return budoAsyncInvocation;
    }

    public static RpcInvocation toDubboInvocation(BudoAsyncInvocation budoAsyncInvocation) {
        RpcInvocation invocation = new RpcInvocation();

        invocation.setMethodName(budoAsyncInvocation.getMethodName());
        invocation.setParameterTypes(budoAsyncInvocation.getParameterTypes());
        invocation.setArguments(budoAsyncInvocation.getArguments());

        Long createdAt = budoAsyncInvocation.getCreatedAt();

        invocation.setAttachment("asyncInvocationCreatedAt", createdAt + ""); // 消息创建时间
        invocation.setAttachment("asyncInvocationId", budoAsyncInvocation.getId() + ""); // 消息ID
        return invocation;
    }
}